package com.graduation.smartparkingplatform.ServiceImpl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.graduation.smartparkingplatform.Dao.ComponentMapper;
import com.graduation.smartparkingplatform.Pojo.Device;
import com.graduation.smartparkingplatform.Pojo.Distinguish;
import com.graduation.smartparkingplatform.Pojo.PayingRecord;
import com.graduation.smartparkingplatform.Pojo.Visitor;
import com.graduation.smartparkingplatform.Service.ComponentService;
import com.graduation.smartparkingplatform.Utils.DateToWeek;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class ComponentServiceImpl implements ComponentService {
  @Autowired ComponentMapper componentMapper;

  // 获取系统访客
  @Override
  public PageInfo<Visitor> getLog(Integer page, Integer count) {
    PageHelper.startPage(page, count);

    List<Visitor> logList = componentMapper.getLog();

    PageInfo<Visitor> pageInfo = new PageInfo<>(logList);

    return pageInfo;
  }

  // 获取访客设备信息
  @Override
  public Map<String, Object> getLogDevice() {

    List<Device> deviceList = componentMapper.getLogDevice();
    Map<String, Object> resultMap = new HashMap<>();
    Map<String, Integer> broswermap = new HashMap<>();
    Map<String, Integer> devicemap = new HashMap<>();
    List<String> broswerList = new ArrayList<>();
    List<String> deviceTypeList = new ArrayList<>();
    for (Device device : deviceList) {
      broswerList.add(device.getUser_broswers());
      deviceTypeList.add(device.getDevice_type());
    }
    for (String broswer : broswerList) {
      if (broswermap.containsKey(broswer)) {
        Integer total = broswermap.get(broswer);
        broswermap.put(broswer, total + 1);
      } else {
        broswermap.put(broswer, 1);
      }
    }
    for (String device : deviceTypeList) {
      if (devicemap.containsKey(device)) {
        Integer total = devicemap.get(device);
        devicemap.put(device, total + 1);
      } else {
        devicemap.put(device, 1);
      }
    }
    resultMap.put("device", devicemap);
    resultMap.put("broswer", broswermap);
    return resultMap;
  }

  // 数据统计信息
  @Override
  public Map<String, Object> getStatistics() throws ParseException {
    Map<String, Object> charts = new HashMap<>();
    Map<String, String> result = new HashMap<>();
    Map<String, Object> all = new HashMap<>();
    // 创建一个数值格式化对象
    NumberFormat numberFormat = NumberFormat.getInstance();
    // 设置精确到小数点后2位
    numberFormat.setMaximumFractionDigits(2);

    Integer spaceTotal = componentMapper.spaceTotal();
    // 今日数据
    Integer distinguishAll_today = componentMapper.distinguishAll("today"); // 总识别数
    Integer distinguishOut_today = componentMapper.distinguish("today", "出"); // 出场数
    Integer distinguishIn_today = componentMapper.distinguish("today", "进"); // 进场数
    Integer visitorCount_today = componentMapper.visitorCount("today"); // 访客数
    // 昨日数据
    Integer distinguishAll_yes = componentMapper.distinguishAll("yesterday"); // 总识别数
    Integer distinguishOut_yes = componentMapper.distinguish("yesterday", "出"); // 出场数
    Integer distinguishIn_yes = componentMapper.distinguish("yesterday", "进"); // 进场数
    Integer visitorCount_yes = componentMapper.visitorCount("yesterday"); // 访客数

    // 昨今比例
    String distinguish_scale;
    String distinguishOut_scale;
    String distinguishIn_scale;
    String visitorCount_scale;
    if (distinguishAll_yes == 0) {
      distinguish_scale = "0";
    } else {
      distinguish_scale =
          numberFormat.format(
              ((float) distinguishAll_today - (float) distinguishAll_yes)
                  / (float) distinguishAll_yes
                  * 100);
    }
    if (distinguishOut_yes == 0) {
      distinguishOut_scale = "0";
    } else {
      distinguishOut_scale =
          numberFormat.format(
              ((float) distinguishOut_today - (float) distinguishOut_yes)
                  / (float) distinguishOut_yes
                  * 100);
    }
    if (distinguishIn_yes == 0) {
      distinguishIn_scale = "0";
    } else {
      distinguishIn_scale =
          numberFormat.format(
              ((float) distinguishIn_today - (float) distinguishIn_yes)
                  / (float) distinguishIn_yes
                  * 100);
    }
    if (visitorCount_yes == 0) {
      visitorCount_scale = "0";
    } else {
      visitorCount_scale =
          numberFormat.format(
              ((float) visitorCount_today - (float) visitorCount_yes)
                  / (float) visitorCount_yes
                  * 100);
    }

    result.put("spaceTotal", spaceTotal.toString());
    result.put("distinguishAll_today", distinguishAll_today.toString());
    result.put("distinguishOut_today", distinguishOut_today.toString());
    result.put("distinguishIn_today", distinguishIn_today.toString());
    result.put("visitorCount_today", visitorCount_today.toString());

    result.put("distinguish_scale", distinguish_scale);
    result.put("distinguishOut_scale", distinguishOut_scale);
    result.put("distinguishIn_scale", distinguishIn_scale);
    result.put("visitorCount_scale", visitorCount_scale);

    List<BigDecimal> incomeList_today = componentMapper.income("today");
    List<BigDecimal> incomeList_yes = componentMapper.income("yesterday");
    List<BigDecimal> incomeList_month = componentMapper.income("month");
    List<BigDecimal> incomeList_lastMonth = componentMapper.income("lastMonth");
    List<BigDecimal> incomeList_quarter = componentMapper.income("quarter");
    List<BigDecimal> incomeList_lastQuarter = componentMapper.income("lastQuarter");
    BigDecimal incomeTotal_today = new BigDecimal(0);
    BigDecimal incomeTotal_yes = new BigDecimal(0);
    BigDecimal incomeTotal_month = new BigDecimal(0);
    BigDecimal incomeTotal_lastMonth = new BigDecimal(0);
    BigDecimal incomeTotal_quarter = new BigDecimal(0);
    BigDecimal incomeTotal_lastQuarter = new BigDecimal(0);

    if (incomeList_today.size() > 0) {
      for (BigDecimal income : incomeList_today) {
        incomeTotal_today = incomeTotal_today.add(income);
      }
    }
    if (incomeList_yes.size() > 0) {
      for (BigDecimal income : incomeList_yes) {
        incomeTotal_yes = incomeTotal_yes.add(income);
      }
    }
    if (incomeList_month.size() > 0) {
      for (BigDecimal income : incomeList_month) {
        incomeTotal_month = incomeTotal_month.add(income);
      }
    }
    if (incomeList_lastMonth.size() > 0) {
      for (BigDecimal income : incomeList_lastMonth) {
        incomeTotal_lastMonth = incomeTotal_lastMonth.add(income);
      }
    }
    if (incomeList_quarter.size() > 0) {
      for (BigDecimal income : incomeList_quarter) {
        incomeTotal_quarter = incomeTotal_quarter.add(income);
      }
    }
    if (incomeList_lastQuarter.size() > 0) {
      for (BigDecimal income : incomeList_lastQuarter) {
        incomeTotal_lastQuarter = incomeTotal_lastQuarter.add(income);
      }
    }
    BigDecimal incomeList_prop_ty;
    BigDecimal incomeList_prop_ml;
    BigDecimal incomeList_prop_ql;
    if (incomeTotal_yes.compareTo(BigDecimal.ZERO) == 0) {
      incomeList_prop_ty = new BigDecimal(0);
    } else {
      incomeList_prop_ty =
          incomeTotal_today
              .subtract(incomeTotal_yes)
              .divide(incomeTotal_yes, 2, BigDecimal.ROUND_HALF_UP);
    }
    if (incomeTotal_lastMonth.compareTo(BigDecimal.ZERO) == 0) {
      incomeList_prop_ml = new BigDecimal(0);
    } else {
      incomeList_prop_ml =
          incomeTotal_month
              .subtract(incomeTotal_lastMonth)
              .divide(incomeTotal_lastMonth, 2, BigDecimal.ROUND_HALF_UP);
    }
    if (incomeTotal_lastQuarter.compareTo(BigDecimal.ZERO) == 0) {
      incomeList_prop_ql = new BigDecimal(0);
    } else {
      incomeList_prop_ql =
          incomeTotal_quarter
              .subtract(incomeTotal_lastQuarter)
              .divide(incomeTotal_lastQuarter, 2, BigDecimal.ROUND_HALF_UP);
    }

    String income_today_new = numberFormat.format(incomeTotal_today.doubleValue());
    String incomeTotal_month_new = numberFormat.format(incomeTotal_month.doubleValue());
    String incomeTotal_quarter_new = numberFormat.format(incomeTotal_quarter.doubleValue());

    result.put("incomeTotal_today", income_today_new);
    result.put("incomeTotal_month", incomeTotal_month_new);
    result.put("incomeTotal_quarter", incomeTotal_quarter_new);
    result.put("incomeList_prop_ty", incomeList_prop_ty.toString());
    result.put("incomeList_prop_ml", incomeList_prop_ml.toString());
    result.put("incomeList_prop_ql", incomeList_prop_ql.toString());

    List<Distinguish> outList = componentMapper.weekDistinguish("出");
    List<Distinguish> inList = componentMapper.weekDistinguish("进");
    Map<String, Integer> distinguishMap_out = new HashMap<>();
    Map<String, Integer> distinguishMap_in = new HashMap<>();
    for (Distinguish distinguish : outList) {
      String date = distinguish.getDred_time();
      String weekDay = DateToWeek.toWeek(date);
      if (distinguishMap_out.containsKey(weekDay)) {
        Integer total = distinguishMap_out.get(weekDay);
        distinguishMap_out.put(weekDay, total + 1);
      } else {
        distinguishMap_out.put(weekDay, 1);
      }
    }
    for (Distinguish distinguish : inList) {
      String date = distinguish.getDred_time();
      String weekDay = DateToWeek.toWeek(date);
      if (distinguishMap_in.containsKey(weekDay)) {
        Integer total = distinguishMap_in.get(weekDay);
        distinguishMap_in.put(weekDay, total + 1);
      } else {
        distinguishMap_in.put(weekDay, 1);
      }
    }
    charts.put("distinguish_out", distinguishMap_out);
    charts.put("distinguish_in", distinguishMap_in);

    all.put("statistics", result);
    all.put("charts", charts);
    return all;
  }

  // 获取车辆进出记录
  @Override
  public PageInfo<Distinguish> getRecord(Integer page, Integer count) {
    PageHelper.startPage(page, count);

    List<Distinguish> recordList = componentMapper.getRecord();

    PageInfo<Distinguish> pageInfo = new PageInfo<>(recordList);

    return pageInfo;
  }

  // 获取收入统计(7日)
  @Override
  public List<Object> weekPayment() throws ParseException {
    List<Object> resultList = new ArrayList<>();
    List<PayingRecord> paymentList = componentMapper.getPayment("week");
    for (PayingRecord PayingRecord : paymentList) {
      Map<String, String> map = new HashMap<>();
      String date = PayingRecord.getPay_time();
      BigDecimal money = PayingRecord.getPay_amount();
      String weekDay = DateToWeek.toWeek(date);
      map.put("weekday", weekDay);
      map.put("money", money.toString());
      resultList.add(map);
    }
    return resultList;
  }

  // 获取收入统计(30日)
  @Override
  public List<Object> monthPayment() {
    List<String> resultList = new ArrayList<>();
    List<PayingRecord> paymentList = componentMapper.getPayment("month");

    Collections.sort(
        paymentList,
        new Comparator<PayingRecord>() {
          @Override
          public int compare(PayingRecord o1, PayingRecord o2) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
              Date dt1 = format.parse(o1.getPay_time());
              Date dt2 = format.parse(o2.getPay_time());
              if (dt1.getTime() > dt2.getTime()) {
                return 1;
              } else {
                return -1;
              }
            } catch (Exception e) {
              log.error("monthPayment to sort error-" + e);
              e.printStackTrace();
            }
            return 0;
          }
        });
    List<Object> objList = new ArrayList<>();

    for (PayingRecord payingRecord : paymentList) {
      Map<String, String> timeToid = new HashMap<>();
      BigDecimal money = payingRecord.getPay_amount();
      String date = payingRecord.getPay_time().substring(8, 10);
      timeToid.put("day", date);
      timeToid.put("money", money.toString());
      objList.add(timeToid);
    }
    return objList;
  }
}
